package com.lch.base.http.exception;

import android.net.ParseException;
import android.nfc.FormatException;
import android.os.NetworkOnMainThreadException;

import com.google.gson.JsonParseException;
import com.lch.base.http.utils.LogUtils;
import com.lch.base.http.HttpConfig;

import org.json.JSONException;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.HashMap;

import javax.net.ssl.SSLPeerUnverifiedException;

import retrofit2.HttpException;


/**
 * Exception错误处理器
 *
 * @author lee(29487113@qq.com) on 17/11/1
 */
public class ExceptionHandler {

    public static ApiException handleException(Throwable e) {
        int mCode;
        String mMsg;

        //服务器返回的错误-可以自定义
        if (e instanceof ApiException) {
            ApiException exception = (ApiException) e;
            mCode = exception.getCode();
            switch (mCode) {
                case HttpCode.ServerError.ERROR_TRANSFORM:
                    mMsg = "返回数据为空或解析失败";
                    break;

                case HttpCode.ServerError.RETURE_DATA_NULL:
                    mMsg = "返回的数据结构data为空或解析失败";
                    break;

                default:
                    mMsg = exception.getMsg(); //获取服务器返回的

                    //判断有没有注入进来的错误列表。有就使用前端自定义的code错误提示
                    HashMap<String, String> errorCodeMap = HttpConfig.getErrorCodeMap();
                    if (errorCodeMap != null && errorCodeMap.containsKey(String.valueOf(mCode))) {
                        mMsg = errorCodeMap.get(String.valueOf(mCode));
                    }
                    break;
            }
        }

        // HTTP错误
        // 有需要可以区分每个code的错误信息 HttpCode.HttpError.xxxx
        else if (e instanceof HttpException) {
            HttpException exception = (HttpException) e;
            mCode = exception.code();
            mMsg = "网络错误";
        }

        //其他错误，解析错误等
        else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) {
            mCode = HttpCode.ServerError.ERROR_TRANSFORM;
            mMsg = "解析错误";
        } else if (e instanceof ConnectException) {
            mCode = HttpCode.ServerError.NET_ERROR;
            mMsg = "连接失败";
        } else if (e instanceof SocketTimeoutException) {
            mCode = HttpCode.ServerError.SOCKET_TIMEOUT;
            mMsg = "连接网络超时";
        } else if (e instanceof UnknownHostException) {
            mCode = HttpCode.ServerError.UNKOWN_HOST;
            mMsg = "服务器地址未找到,请检查网络或Url";
        } else if (e instanceof NetworkOnMainThreadException) {
            mCode = HttpCode.ServerError.MAIN_HTREAD;
            mMsg = "网络请求不能在主线程处理";
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            mCode = HttpCode.ServerError.SSL_ERROR;
            mMsg = "证书验证失败";
        } else if (e instanceof java.security.cert.CertPathValidatorException) {
            mCode = HttpCode.ServerError.SSL_NOT_FOUND;
            mMsg = "书路径没找到";
        }

        //OkHttpClient.hostnameVerifier的一个叫verify的方法,验证返回false就会报这个错，可以去加入白名单或者全部通过返回true
        else if (e instanceof SSLPeerUnverifiedException) {
            mCode = HttpCode.ServerError.SSL_NOT_FOUND;
            mMsg = "无有效的SSL证书";
        } else if (e instanceof java.lang.ClassCastException) {
            mCode = HttpCode.ServerError.CLASS_CAST;
            mMsg = "类型转换出错";
        } else if (e instanceof NullPointerException) {
            mCode = HttpCode.ServerError.NULL;
            mMsg = "数据有空";
        } else if (e instanceof FormatException) {
            mCode = HttpCode.ServerError.FORMAT_FAIL;
            mMsg = "FormatException";
        } else {
            mCode = HttpCode.ServerError.UNKNOWN;
            mMsg = "未知错误";
        }

        e.printStackTrace();

        LogUtils.e("ExceptionHandler 返回错误:" + " code:" + mCode + "   msg:" + mMsg);

        return new ApiException(e, mCode, mMsg);
    }
}
